#define LOAD        ld
#define STORE       sd
#define REGBYTES    8

.macro reg_save base
    STORE ra, 0*REGBYTES(\base)
    STORE sp, 1*REGBYTES(\base)
    STORE gp, 2*REGBYTES(\base)
    STORE tp, 3*REGBYTES(\base)
    STORE t0, 4*REGBYTES(\base)
    STORE t1, 5*REGBYTES(\base)
    STORE t2, 6*REGBYTES(\base)
    STORE s0, 7*REGBYTES(\base)
    STORE s1, 8*REGBYTES(\base)
    STORE a0, 9*REGBYTES(\base)
    STORE a1, 10*REGBYTES(\base)
    STORE a2, 11*REGBYTES(\base)
    STORE a3, 12*REGBYTES(\base)
    STORE a4, 13*REGBYTES(\base)
    STORE a5, 14*REGBYTES(\base)
    STORE a6, 15*REGBYTES(\base)
    STORE a7, 16*REGBYTES(\base)
    STORE s2, 17*REGBYTES(\base)
    STORE s3, 18*REGBYTES(\base)
    STORE s4, 19*REGBYTES(\base)
    STORE s5, 20*REGBYTES(\base)
    STORE s6, 21*REGBYTES(\base)
    STORE s7, 22*REGBYTES(\base)
    STORE s8, 23*REGBYTES(\base)
    STORE s9, 24*REGBYTES(\base)
    STORE s10, 25*REGBYTES(\base)
    STORE s11, 26*REGBYTES(\base)
    STORE t3, 27*REGBYTES(\base)
    STORE t4, 28*REGBYTES(\base)
    STORE t5, 29*REGBYTES(\base)
.endm

.macro reg_restore base
    LOAD ra, 0*REGBYTES(\base)
    LOAD sp, 1*REGBYTES(\base)
    LOAD gp, 2*REGBYTES(\base)
    LOAD tp, 3*REGBYTES(\base)
    LOAD t0, 4*REGBYTES(\base)
    LOAD t1, 5*REGBYTES(\base)
    LOAD t2, 6*REGBYTES(\base)
    LOAD s0, 7*REGBYTES(\base)
    LOAD s1, 8*REGBYTES(\base)
    LOAD a0, 9*REGBYTES(\base)
    LOAD a1, 10*REGBYTES(\base)
    LOAD a2, 11*REGBYTES(\base)
    LOAD a3, 12*REGBYTES(\base)
    LOAD a4, 13*REGBYTES(\base)
    LOAD a5, 14*REGBYTES(\base)
    LOAD a6, 15*REGBYTES(\base)
    LOAD a7, 16*REGBYTES(\base)
    LOAD s2, 17*REGBYTES(\base)
    LOAD s3, 18*REGBYTES(\base)
    LOAD s4, 19*REGBYTES(\base)
    LOAD s5, 20*REGBYTES(\base)
    LOAD s6, 21*REGBYTES(\base)
    LOAD s7, 22*REGBYTES(\base)
    LOAD s8, 23*REGBYTES(\base)
    LOAD s9, 24*REGBYTES(\base)
    LOAD s10, 25*REGBYTES(\base)
    LOAD s11, 26*REGBYTES(\base)
    LOAD t3, 27*REGBYTES(\base)
    LOAD t4, 28*REGBYTES(\base)
    LOAD t5, 29*REGBYTES(\base)
    LOAD t6, 30*REGBYTES(\base)
.endm

.text

 .global switch_to
 .balign 8
switch_to:
    csrrw t6, sscratch, t6
    beqz t6, 1f
    reg_save t6
    mv t5, t6
    csrr t6, sscratch
    STORE t6, 30*REGBYTES(t5)
1:  
    csrw sscratch, a0
    mv t6, a0
    reg_restore t6
    ret

.end